package org.lisy.java.oop;

/**
 * 面向对象
 * @author lisy
 */
public class OopOperate {

	public static void main(String[] args) {
		// 对象一建立就会调用与之对应的构造函数
		Car car = new Car();
        System.out.println(car.color + "的小汽车");
        System.out.println(car.num + "个轮子");
        car.run();
        
        // 匿名换句话其实就是没有名字的意思，匿名对象两种使用情况
        new Car().num = 5; //1.当对对象方法仅进行一次调用的时候
        System.out.println(new Car().color + "的小汽车"); // 2.匿名对象可以作为实际参数进行传递
        
        // 封装原则	将不需要对外提供的内容都隐藏起来； 把属性都隐藏，提供对外访问方式
        showString("我是封装");
        
        // private 类名.方法调用，或提供get/set方法
        car.color = "green";
        car.run();
        LittleCar littleCar = new LittleCar();
        littleCar.run();
        BigCar bigCar = new BigCar();
        bigCar.run();
    }
	
	/**
	 * 函数就是一个小的封装
	 * @param str
	 */
	public static void showString(String str) {
        System.out.println(str);
    }
}

/**
 * 汽车类
 * @author lisy
 */
class Car {
    // 属性和行为组成成员变量
    String color = "红色";
    int num = 4;
    /**
     * 代码块
     * 作用：给对象初始化，而且优先于构造方法
     * 比较：构造代码块是给所有对象进行统一初始化	而构造函数是给对应的对象初始化
     */
    {
    	System.out.println("我是父类代码块");
    }
    static {
    	// 静态代码块的特点：随着类的加载而执行，只执行一次
    	System.out.println("静态代码块");
    }
    
    /**
     * 构造方法
     * 特点：函数名和类名相同     不用定义返回值类型    不可以写return语句
     * 作用：给对象进行初始化
     * 注意：系统默认给该类加入一个空参数构造方法 当该类定义了构造方法，默认的就没有了，构造方法用了重载
     */
    public Car() {
    	System.out.println("我是父类构造方法");
    }
    public Car(String color, int num) {
        System.out.println("我是父类构造方法" + num);
    }
    // 行为
    void run() {
        System.out.println("我是" + color + "的小汽车，我有" + num + "个轮子");
    }
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
}

/**
 * 继承类
 * @author lisy
 */
class BigCar extends Car{

	/**
	 * 多态
	 * 好处：
	 *  1.提高复用性	
	 *  2.类的功能可以被基类的方法或引用变量所调用，这叫向后兼容，可以提高可扩充性和可维护性
	 * 体现：可以用在方法的参数中和方法的返回类型中
	 */
	void run() {
        System.out.println("big子类run方法");
    }
}

/**
 * 继承类
 * @author lisy
 */
class LittleCar extends Car{
	/**
	 * 继承
	 * 作用：
	 *  1.提高代码的复用性 
	 *  2.让类与类之间产生关系，有了这层关系才有了多态的特性
	 * 特点：
	 * 	1.子类的所有的构造函数，默认都会访问父类中空参数的构造函数，因为子类每一个构造函数内的第一行都有一句隐式的super，当父类中没有空参数的构造函数时，子类必须手动通过super或者this语句的形式指定要访问父类中的构造函数
	 * 	2.子类可以重写父类方法
	 */
	void run() {
        System.out.println("little子类run方法");
    }
}
